import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { Http, Request, RequestOptionsArgs, RequestMethod, Response, Headers, RequestOptions, URLSearchParams } from '@angular/http';
import { Observable } from 'rxjs/Rx';

// 服务
import { SessionStorageService } from '../store';
import { TBase64 } from '../utils';

@Injectable()
export class AuthService {
    private sessionIDKey = 'session_id';

    redirectURL: string;
    count: any;
    crecount:boolean;
    constructor(
        private http: Http,
        private sessionStorage: SessionStorageService,
        private router: Router
    ) { }

    get isLoggedIn(): boolean {
        const data = this.sessionStorage.getValue(this.sessionIDKey);

        let isLogin = data ? true : false;
        if (isLogin) {
            isLogin = !this.isExpired;
            if (!isLogin) {
                this.sessionStorage.remove(this.sessionIDKey);
            }
        }
        if (isLogin) {
            this.autoRefreshToken();
        }
        return isLogin;
    }

    get sessionID(): string {
        if (this.isLoggedIn) {
            if (this.isExpired) {
                this.logout();
                // this.refreshToken().then(token => { console.log(`更换令牌：${token}`); });
            }
        }
        return this.sessionStorage.getValue(this.sessionIDKey);
    }

    set sessionID(sessionID: string) {
        this.sessionStorage.setValue(this.sessionIDKey, sessionID);
        //this.printToken()
        this.autoRefreshToken();

    }
    autoRefreshToken(): void {
        if (this.count == null) {

            this._auto();
        }
    }
    _auto(): void {
        if (this.crecount) {
            return
        }
        const stime = (this.sessionExp - Date.now() / 1000 - 60) * 1000
        if (stime <= 0) {
            this.crecount=true
            this.refreshToken().then(() => {
                this.crecount=false;
                //console.log("auto------")
               this._auto();
            }).catch(()=> this.logout());
        } else {
            this.count = setInterval(() => {
                if (!!!this.sessionID) {
                    this.logout();

                    return;
                }
                this.refreshToken();
            }, stime);
            
        }


    }
    // 检查是否过期
    get isExpired(): boolean {
        const exp = this.sessionExp;
        const ct = Date.now() / 1000;

        return exp < ct;
    }

    // 获取session过期时间
    get sessionExp(): number {
        const sessionID = this.sessionStorage.getValue(this.sessionIDKey);
        const payloads = sessionID.split('.');
        if (payloads.length !== 3) {
            return 0;
        }
        const dstr = TBase64.decode(payloads[1]);
        const claims = JSON.parse(dstr);

        return claims.exp || 0;
    }
    // printToken(): void {
    //     const sessionID = this.sessionStorage.getValue(this.sessionIDKey);
    //     const payloads = sessionID.split('.');
    //     if (payloads.length !== 3) {
    //         return;
    //     }
    //     const dstr = TBase64.decode(payloads[1]);
    //     console.log(dstr)
    // }
    // 登出
    logout() {
        clearInterval(this.count)
        this.count = null
        if (!this.isLoggedIn) {
            return;
        }
        this.sessionStorage.remove(this.sessionIDKey);
        this.router.navigate(['/login']);
    }

    // 更新用户令牌
    refreshToken(): Promise<string> {
        return this.http.request(new Request({
            url: '/v1/auth/refresh_token',
            method: RequestMethod.Post,
            body: JSON.stringify({ token: this.sessionID })
        })).toPromise()
            .then((res) => {
                const body = res.json();
                return body || {};
            })
            .then(token => {
                this.sessionID = token.token;
                return token.token;
            })
            .catch((error: Response | any) => {

                let errMsg: string;
                let errCode: number;
                if (error instanceof Response) {
                    let err: string;
                    try {
                        const body = error.json();
                        err = body.msg;
                    } catch (e) {
                        err = '';
                    }
                    errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
                } else {
                    errMsg = error.message ? error.message : error.toString();
                }
               // console.log(errMsg)
                this.logout()
                return Promise.reject(errMsg);
            });
    }
}
